/*
 * Copyright (c) 2019. Mikes. All rights reserved.
 *
 * You can contact me with sending email to bWlrZXNfMjAxMkAxNjMuY29t for more information!
 */

package com.climber.android.commonres

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import com.climber.android.commonres.app.service.CoreService
import com.climber.android.commonsdk.api.GlobalErrorProcessor
import com.climber.android.commonsdk.api.entity.APIResponseData
import io.ganguo.library.mvp.http.RxSchedulers
import io.ganguo.library.mvp.http.upload.FileUploadObserver
import io.ganguo.library.mvp.http.upload.ProgressRequestBody
import io.ganguo.library.mvp.util.RxLifecycleUtils
import io.ganguo.library.mvp.util.ToastHelper
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
import java.io.UnsupportedEncodingException
import java.net.URLEncoder

data class UploadFile(var url : String?)

enum class UploadType{
    AVATAR;                         //头像上传

    fun apiType() : String = when(this){
        AVATAR -> "1"
    }
}

/**
 * Created by Mikes at 2019-11-11 19:35
 */
object UploadFileUtil {
    @JvmStatic
    fun doUploadFile(lifecycleOwner : LifecycleOwner, pendingUploadFile : File, uploadType : UploadType, completion : (String?) -> Unit){
        val fileUploadObserver = object : FileUploadObserver<APIResponseData<UploadFile>>(){
            override fun onProgress(progress: Int) {
            }

            override fun onNext(result: APIResponseData<UploadFile>) {
                super.onNext(result)

                if(result.isSuccessful()){
                    completion(result.data?.url)
                } else{
                    completion(null)
                }
            }

            override fun onError(e: Throwable) {
                super.onError(e)

                ToastHelper.toastMessage("上传图片失败，请稍后重试")
                completion(null)
            }
        }

        CoreService.coreServiceAPI.issueUploadSingleFile(
            generateUploadFileBody(
                uploadFile = pendingUploadFile,
                mimeType = "image/*",
                additionalParams = mapOf(
                    "type" to uploadType.apiType()
                ),
                fileUploadObserver = fileUploadObserver)
            )
            .compose(RxSchedulers.networkRequest())
            .compose(GlobalErrorProcessor.processGlobalError(true))
            .`as`(RxLifecycleUtils.bindUntilEvent(lifecycleOwner, Lifecycle.Event.ON_DESTROY))
            .subscribe(fileUploadObserver)
    }

    @JvmStatic
    private fun <Result> generateUploadFileBody(
        uploadFile: File,
        mimeType: String,
        additionalParams: Map<String, String>?,
        fileUploadObserver: FileUploadObserver<Result>
    ): MultipartBody {
        val multiPartBodyBuilder = MultipartBody.Builder()

        val uploadFileRequestBody = ProgressRequestBody(
            RequestBody.create(MediaType.parse(mimeType), uploadFile),
            fileUploadObserver
        )

        additionalParams?.let {
            //uploadType : uploadType
            for ((key, value) in it) {
                multiPartBodyBuilder.addFormDataPart(key, value)
            }
        }
        multiPartBodyBuilder.addFormDataPart("image", getValueEncoded(uploadFile.name), uploadFileRequestBody)

        multiPartBodyBuilder.setType(MultipartBody.FORM)
        return multiPartBodyBuilder.build()
    }

    //\n null 中文等特殊字符 返回encode后的字符串
    private fun getValueEncoded(value: String?): String {
        if (value == null) return "null"
        val newValue = value.replace("\n", "")
        var i = 0
        val length = newValue.length
        while (i < length) {
            val c = newValue[i]
            if (c <= '\u001f' || c >= '\u007f') {
                try {
                    return URLEncoder.encode(newValue, "UTF-8")
                } catch (e: UnsupportedEncodingException) {
                    e.printStackTrace()
                }
            }
            i++
        }
        return newValue
    }
}